﻿using System;
using System.Windows;
using System.Windows.Shapes;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Collections.Generic;
namespace GoL_Silverlight
{
	public partial class GolSim : UserControl
	{
		bool[,] crds;
		Brush iBr = new SolidColorBrush(Color.FromArgb(255, 99, 99, 99)), aBr = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
		Point gDim;
		double cSize = 5;
		int spd = 500000;
		List<Point> ucrds = new List<Point>();
		int i, j, c;
		public Boolean a;
		public DispatcherTimer tmr;

		public GolSim(bool[,] c)
		{
			InitializeComponent();
			gDim = new Point(c.GetLength(0), c.GetLength(1));
			crds = c;
			tmr = new DispatcherTimer { Interval = new TimeSpan(spd) };
			tmr.Tick += new EventHandler(Tick);
			DrawGrid();
		}
		void DrawGrid()
		{
			for (i = 0; i < gDim.X; i++)
			{
				g.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(cSize) });
			}
			for (i = 0; i < gDim.Y; i++)
			{
				g.RowDefinitions.Add(new RowDefinition { Height = new GridLength(cSize) });
			}
			for (i = 0; i < gDim.Y; i++)
			{
				for (j = 0; j < gDim.X; j++)
				{
					Rectangle r = new Rectangle { Width = cSize, Height = cSize, Fill = iBr, Margin = new Thickness(0) };
					r.SetValue(Grid.RowProperty, i);
					r.SetValue(Grid.ColumnProperty, j);
					r.Tag = new Point(j, i);
					r.MouseLeftButtonUp += new MouseButtonEventHandler(sClick);
					g.Children.Add(r);
				}
			}
			Update(true);
		}
		void sClick(object s, MouseButtonEventArgs e)
		{
			if (a)
			{
				Point pt = (Point)((Rectangle)s).Tag;
				crds[(int)pt.X, (int)pt.Y] = !crds[(int)pt.X, (int)pt.Y];
				((Rectangle)s).Fill = crds[(int)pt.X, (int)pt.Y] ? aBr : iBr;
			}
		}
		void Tick(object s, EventArgs e)
		{
			ucrds.Clear();
			bool[,] newCrds = (bool[,])crds.Clone();
			for (c = 0; c < gDim.Y; c++)
			{
				for (int l = 0; l < gDim.X; l++)
				{
					int n = 0;
					if (l != 0 && c != 0 && crds[l - 1, c - 1])
						n++;
					if (c != 0 && crds[l, c - 1])
						n++;
					if (l != gDim.X - 1 && c != 0 && crds[l + 1, c - 1])
						n++;
					if (l != gDim.X - 1 && crds[l + 1, c])
						n++;
					if (l != gDim.X - 1 && c != gDim.Y - 1 && crds[l + 1, c + 1])
						n++;
					if (c != gDim.Y - 1 && crds[l, c + 1])
						n++;
					if (l != 0 && c != gDim.Y - 1 && crds[l - 1, c + 1])
						n++;
					if (l != 0 && crds[l - 1, c])
						n++;
					if (n > 3 || n < 2)
						newCrds[l, c] = false;
					if (n == 3)
						newCrds[l, c] = true;
					if (newCrds[l, c] != crds[l, c])
						ucrds.Add(new Point(l, c));
				}
			}
			crds = (bool[,])newCrds.Clone();
			Update(false);
		}
		void Update(bool rfrsh)
		{
			c = 0;
			for (i = 0; i < gDim.Y; i++)
			{
				for (j = 0; j < gDim.X; j++)
				{
					if (rfrsh || (ucrds.Count > 0 && ucrds[0] == new Point(j, i)))
                    {
						if (crds[j, i])
							((Rectangle)g.Children[c]).Fill = aBr;
						else
							((Rectangle)g.Children[c]).Fill = iBr;
						if(ucrds.Count > 0)
							ucrds.RemoveAt(0);
                    }
					c++;
				}
			}
		}
	}
}